#include <cnet.h>

/* Longitud en bytes de una dirección IP v4 */
#define IP_ADDRLEN 4

/* Evento producido cuando la capa de red tiene mensajes para enviar
 * En esta implementacion simplificada, la capa de red pasa los mensajes de
 * la capa de aplicación 1 a 1
 */
#define EV_NETWORKREADY EV_APPLICATIONREADY

/*
 * Dirección IP v4, en formato network-endian
 * Nota: la implementación actual supone que el host es little-endian
 */
typedef uint32_t IPAddress;

/* network_local_address(ip) devuelve la dirección IP local del enlace lan de este
 * nodo. en la topología dada, es la dirección IP del único enlace (hay un
 * enlace loopback que no usamos)
 *
 * Devuelve direcciones en una red clase C predeterminada (o sea, hay hasta
 * 254 direcciones posibles.)
 * POST: network_is_valid(result);
 */
 IPAddress network_local_address(void);

/* network_is_valid(ip) devuelve true cuando ip es una dirección IP valida
 * y dentro de la clase C simulada.
 */
bool network_is_valid(IPAddress ipaddr);

/* network_read_network(&destino, mensaje, &longitud) lee un mensaje de la capa
 * de red que necesita ser enviado a destino. Normalmente
 * esta funcion es llamada desde el manejador del evento EV_NETWORKREADY.
 *
 * Para más información consultar la documentacion de CNET_read_application,
 * que tienen una interfaz similar
 * Pre: longitud >= 0
 *      mensaje es un buffer de al menos longitud bytes
 *      &destino != NULL, apunta a una variable del tamaño de una dirección IP
 * Post: network_is_valid(destino)
 *       length >= 0
 */
int network_read_network(IPAddress *destaddr, void *message, size_t *length);

/* network_write_network(mensaje, &longitud) pasa a la capa de red un mensaje
 * recibido.
 *
 * Para más información consultar la documentacion de CNET_write_application,
 * que tienen una interfaz similar
 * Pre: longitud >= 0
 *      mensaje es un buffer de al menos longitud bytes
 * Post: longitud >= 0
 */
int network_write_network(void *message, size_t *length);

/* network_pause_destination(dest) le indica a la capa de red del nodo actual
 * que temporalmente deje de generar mensajes dirigidos hacia dest. Esto simula
 * bloquear a un programa que está enviando.
 * La capa de red permanece bloqueada hasta la siguiente llamada a
 * network_unpause_destination
 * Pre: network_is_valid(dest);
 */
int network_pause_destination(IPAddress destaddr);
 
/* network_unpause_destination(dest) le indica a la capa de red del nodo actual
 * que puede volver a generar mensajes dirigidos hacia dest. Esto simula
 * desbloquear a un programa que está enviando.
 * Pre: network_is_valid(dest);
 */
int network_unpause_destination(IPAddress destaddr);
 
/* network_display_address(ip) devuelve una cadena (alojada en buffer estático)
 * con la representación decimal de ip (ej "192.168.32.15")
 * Puede representar cualquier dirección (aún si no es válida). Util para
 * propósitos de testing/debugging
 */
const char *network_display_address(IPAddress ipaddr); 

